package people.paper.tv.activity.home.modual.sptt.presenter.impl;

import android.content.Context;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.coocaa.app.support.net.Callback;
import com.coocaa.app.support.net.Result;
import com.danikula.videocache.HttpProxyCacheServer;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import people.paper.tv.BaseApplication;
import people.paper.tv.activity.home.HomeFragment;
import people.paper.tv.activity.home.model.MainDataObject;
import people.paper.tv.activity.home.modual.sptt.model.SPTTModel;
import people.paper.tv.activity.home.modual.sptt.presenter.SPTTPresenter;
import people.paper.tv.activity.home.modual.sptt.view.SPTTView;
import people.paper.tv.activity.home.modual.sptt.view.data.VideoData;
import tv.danmaku.ijk.media.player.IMediaPlayer;
import tv.danmaku.ijk.media.player.IjkMediaPlayer;

public class SPTTPresenterImpl implements SPTTPresenter {
    private static class PlayerHandler extends Handler {
        public PlayerHandler(Looper looper) {
            super(looper);
        }

        public void execute(Runnable runnable) {
            if (Looper.myLooper() == getLooper())
                runnable.run();
            else
                post(runnable);
        }

        public void execute(long delay, Runnable runnable) {
            postDelayed(runnable, delay);
        }
    }

    private static final HttpProxyCacheServer proxy = new HttpProxyCacheServer(BaseApplication.getContext());
    private static final HandlerThread handlerThread = new HandlerThread("sptt_player");
    private static PlayerHandler playerHandler;

    static {
        handlerThread.start();
        playerHandler = new PlayerHandler(handlerThread.getLooper());
    }

    private IjkMediaPlayer mediaPlayer;
    //    private SurfaceView surfaceView;
    private Context context;
    private SPTTView view;
    private SPTTModel model;
    private HomeFragment homeFragment;

    private List<MainDataObject.SPTTObject> playLists = new ArrayList<>();
    private Integer playIndex = -1;
    private MainDataObject.SPTTObject playingObject;

    private void createSurfaceView(MainDataObject.SPTTObject object) {
        view.clearVideoPlayer();
        SurfaceView surfaceView = new SurfaceView(context);
        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(final SurfaceHolder holder) {
                playerHandler.execute(new Runnable() {
                    @Override
                    public void run() {
                        Log.d("RMRB", "surfaceCreated:" + holder + "  mediaPlayer:" + mediaPlayer);
                        if (mediaPlayer != null)
                            mediaPlayer.setDisplay(holder);
                    }
                });
            }

            @Override
            public void surfaceChanged(final SurfaceHolder holder, int format, int width, int height) {
                playerHandler.execute(new Runnable() {
                    @Override
                    public void run() {
                        Log.d("RMRB", "surfaceChanged:" + holder + "  mediaPlayer:" + mediaPlayer);
                        if (mediaPlayer != null)
                            mediaPlayer.setDisplay(holder);
                    }
                });
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {

            }
        });
        view.setVideoPlayer(surfaceView, object.symbol.equals(MainDataObject.SPTTObject.LANDSCAPE));
    }
//
//    private void createSurfaceView(final MainDataObject.SPTTObject object) {
//        view.clearVideoPlayer();
//        surfaceView = new SurfaceView(context);
//        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
//            boolean bCreated = false;
//
//            @Override
//            public void surfaceCreated(final SurfaceHolder holder) {
//                Log.d("RMRB", "surfaceCreated:" + surfaceView + "  bCreated:" + bCreated);
////                updatePlayerSurface(holder);
//                initTimer();
//                playerHandler.execute(new Runnable() {
//                    @Override
//                    public void run() {
//                        Log.d("RMRB", "play " + object.videoUrl);
//                        if (!bCreated) {
//                            bCreated = true;
//                            try {
//                                createPlayer(object, holder);
//                                mediaPlayer.setDataSource(context, Uri.parse(proxy.getProxyUrl(object.videoUrl)));
//                                mediaPlayer.prepareAsync();
//                            } catch (IOException e) {
//                                e.printStackTrace();
//                            }
//                        } else {
//                            mediaPlayer.setDisplay(null);
//                            mediaPlayer.setDisplay(holder);
//                        }
//                    }
//                });
//            }
//
//            @Override
//            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
//                Log.d("RMRB", "surfaceChanged:" + surfaceView);
//                updatePlayerSurface(holder);
//
//            }
//
//            @Override
//            public void surfaceDestroyed(SurfaceHolder holder) {
//            }
//        });
//        Log.d("RMRB", "createSurfaceView:" + surfaceView);
//        view.setVideoPlayer(surfaceView, object.symbol.equals(MainDataObject.SPTTObject.LANDSCAPE));
//    }

    @Override
    public void create(Context context, SPTTView view, SPTTModel model, HomeFragment homeFragment) {
        this.context = context;
        this.view = view;
        this.model = model;
        this.homeFragment = homeFragment;
    }

    @Override
    public void start() {
//        try {
//            IjkMediaPlayer.loadLibrariesOnce(null);
//            IjkMediaPlayer.native_profileBegin("libijkplayer.so");
//            IjkMediaPlayer.
//        } catch (Exception e) {
//        }
        initTimer();
        showPageAt(-1);
//        surfaceView = new SurfaceView(context);
//        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
//            @Override
//            public void surfaceCreated(SurfaceHolder holder) {
//                updatePlayerSurface(holder);
//                if (bStarted)
//                    return;
//                bStarted = true;
//                showPageAt(-1);
//                initTimer();
////                createPlayer(holder);
////                playPlayer("http://www.w3school.com.cn/i/movie.mp4");
//            }
//
//            @Override
//            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
////                updatePlayerSurface(holder);
////                createPlayer(holder);
//            }
//
//            @Override
//            public void surfaceDestroyed(SurfaceHolder holder) {
////                releasePlayer();
//            }
//        });
    }

    @Override
    public void resume() {
//        view.setVideoPlayer(surfaceView);
        Log.d("sptt","resume");
        synchronized (this) {
            if (playingObject != null)
                playPlayer(playingObject.index, playingObject);
        }
    }

    @Override
    public void pause() {
        Log.d("sptt","pause");
        releasePlayer();
        view.clearVideoPlayer();
        view.stopPlay();
    }

    @Override
    public void onActivityStart() {
        if (homeFragment.isCurrentFragment())
            resume();
    }

    @Override
    public void onActivityResume() {
    }

    @Override
    public void onActivityPause() {

    }

    @Override
    public void onActivityStop() {
        pause();
    }

    @Override
    public void destroy() {
//        surfaceView = null;
//        IjkMediaPlayer.native_profileEnd();
    }

    @Override
    public void showPageAt(int pageIndex) {
        final int _pageIndex = pageIndex + 1;
        model.get(_pageIndex, new Callback<Result<List<MainDataObject.SPTTObject>>>() {
            @Override
            public Ret onResult(Result<List<MainDataObject.SPTTObject>> result) {
                if (_pageIndex == 0 && result.exception != null) {
                    view.showError(-1);
                } else {
                    List<VideoData> dataList = new ArrayList<>();
                    if (result != null && result.data != null) {
                        synchronized (playLists) {
                            int start = playLists.size();
                            for (final MainDataObject.SPTTObject object : result.data) {
                                object.index = start + result.data.indexOf(object);
//                            object.videoUrl = "http://www.w3school.com.cn/i/movie.mp4";
//                            object.videoUrl = "http://v-play.coocaatv.com/shijiebei/renwu/fuyao.mp4";
                                VideoData d = new VideoData();
                                d.title = object.videoTitle;
                                d.onPlay = new Runnable() {
                                    @Override
                                    public void run() {
                                        playPlayer(object.index, object);
                                    }
                                };
                                dataList.add(d);
                            }
                            playLists.addAll(result.data);
                        }
                    }
                    view.onVideoNewsLoaded(_pageIndex, dataList);
                }
                return new Ret(0, "success~success~success~success");
            }
        });
    }

    @Override
    public void seek(final long pos) {
        playerHandler.execute(new Runnable() {
            @Override
            public void run() {
                if (mediaPlayer != null) {
                    mediaPlayer.seekTo((int) pos);
                    if (!mediaPlayer.isPlaying())
                        mediaPlayer.start();
                }
            }
        });
    }

    private void createPlayer(final MainDataObject.SPTTObject object) {
        playerHandler.execute(new Runnable() {
            @Override
            public void run() {
                mediaPlayer = new IjkMediaPlayer();//new MediaPlayer();
//                mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1);
//                mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", 1);
//                mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-handle-resolution-change", 1);
//                mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzeduration", 1);
//                MediaPlayer.native_setLogLevel(MediaPlayer.IJK_LOG_DEBUG);
                mediaPlayer.setOnPreparedListener(new IMediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(IMediaPlayer mp) {
                        mediaPlayer.start();
                        view.stopLoading();
                        view.startPlay();
                    }
                });
                mediaPlayer.setOnInfoListener(new IMediaPlayer.OnInfoListener() {
                    @Override
                    public boolean onInfo(IMediaPlayer iMediaPlayer, int what, int extra) {
                        Log.d("RMRB", "player onInfo " + what);
                        switch (what) {
                            case MediaPlayer.MEDIA_INFO_BUFFERING_START:
                                view.startLoading();
                                break;
                            case MediaPlayer.MEDIA_INFO_BUFFERING_END:
                                view.stopLoading();
                                view.startPlay();
                                break;
                            default:
                                break;
                        }
                        return false;
                    }
                });
                mediaPlayer.setOnCompletionListener(new IMediaPlayer.OnCompletionListener() {
                    @Override
                    public void onCompletion(IMediaPlayer mp) {
                        Log.d("RMRB", "player onCompletion");
                        playNext();
                    }
                });
                mediaPlayer.setOnErrorListener(new IMediaPlayer.OnErrorListener() {
                    @Override
                    public boolean onError(IMediaPlayer mp, int what, int extra) {
                        Log.d("RMRB", "player onError " + what + "/" + extra);
                        playerHandler.execute(3000, new Runnable() {
                            @Override
                            public void run() {
                                playNext();
                            }
                        });
                        return true;
                    }
                });
                try {
                    mediaPlayer.setDataSource(object.videoUrl);
                    mediaPlayer.prepareAsync();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                Log.d("RMRB", "createPlayer " + mediaPlayer);
            }
        });
    }


    private void releasePlayer() {
        playerHandler.execute(new Runnable() {
            @Override
            public void run() {
                if (mediaPlayer != null) {
                    Log.d("RMRB", "releasePlayer " + mediaPlayer);
//                    mediaPlayer.setDisplay(null);
                    mediaPlayer.release();
                    mediaPlayer = null;
                }
            }
        });
    }

    private synchronized void playNext() {
        synchronized (playLists) {
            synchronized (playIndex) {
                Log.d("RMRB", "playNext " + playIndex);
                if (playIndex >= 0) {
                    int _playIndex = playIndex + 1;
                    Log.d("RMRB", "_playIndex " + _playIndex + "  size:" + (playLists.size() - 1));
                    if (_playIndex < playLists.size()) {
                        MainDataObject.SPTTObject object = playLists.get(_playIndex);
                        playPlayer(_playIndex, object);
                    }
                }
            }
        }
    }

    @Override
    public void playOrPause() {
        playPlayer(playIndex, playingObject);
    }

    private void playPlayer(final int index, final MainDataObject.SPTTObject object) {
        playerHandler.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    if (mediaPlayer != null) {
                        if (playingObject == object) {
                            if (mediaPlayer.isPlaying()) {
                                mediaPlayer.pause();
                                view.stopPlay();
                            } else {
                                mediaPlayer.start();
                                view.startPlay();
                            }
                            return;
                        } else {
                            releasePlayer();
                        }
                    }
                    createPlayer(object);
                    createSurfaceView(object);
                    synchronized (playIndex) {
                        playingObject = object;
                        playIndex = index;
                        view.setCurPlayId(index);
                    }
                    view.startLoading();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    private boolean bTimerOn = false;

    private void initTimer() {
        playerHandler.execute(new Runnable() {
            @Override
            public void run() {
                if (!bTimerOn) {
                    bTimerOn = true;
                    playerHandler.execute(1000, new Runnable() {
                        @Override
                        public void run() {
                            if (mediaPlayer != null) {
                                long pos = mediaPlayer.getCurrentPosition();
                                long duration = mediaPlayer.getDuration();
                                view.refreshDuration(duration, pos);
                            }
                            playerHandler.execute(1000, this);
                        }
                    });
                }
            }
        });
    }
}
